﻿// Decompiled with JetBrains decompiler
// Type: UnityEngine.Cubemap
// Assembly: UnityEngine.CoreModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
// MVID: E6AE6B5A-2752-4B07-9528-C8B77C62CE79
// Assembly location: C:\Users\windys\Unity\2021.3.39f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.CoreModule.dll
// XML documentation location: C:\Users\windys\Unity\2021.3.39f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.CoreModule.xml

using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using Unity.Collections;
using Unity.Collections.LowLevel.Unsafe;
using UnityEngine.Bindings;
using UnityEngine.Experimental.Rendering;
using UnityEngine.Internal;
using UnityEngine.Scripting;

#nullable disable
namespace UnityEngine
{
  /// <summary>
  ///   <para>Class for handling cube maps, Use this to create or modify existing.</para>
  /// </summary>
  [ExcludeFromPreset]
  [NativeHeader("Runtime/Graphics/CubemapTexture.h")]
  public sealed class Cubemap : Texture
  {
    /// <summary>
    ///   <para>The format of the pixel data in the texture (Read Only).</para>
    /// </summary>
    public extern TextureFormat format { [NativeName("GetTextureFormat"), MethodImpl(MethodImplOptions.InternalCall)] get; }

    [FreeFunction("CubemapScripting::Create")]
    [MethodImpl(MethodImplOptions.InternalCall)]
    private static extern bool Internal_CreateImpl(
      [Writable] Cubemap mono,
      int ext,
      int mipCount,
      GraphicsFormat format,
      TextureColorSpace colorSpace,
      TextureCreationFlags flags,
      IntPtr nativeTex);

    private static void Internal_Create(
      [Writable] Cubemap mono,
      int ext,
      int mipCount,
      GraphicsFormat format,
      TextureColorSpace colorSpace,
      TextureCreationFlags flags,
      IntPtr nativeTex)
    {
      if (!Cubemap.Internal_CreateImpl(mono, ext, mipCount, format, colorSpace, flags, nativeTex))
        throw new UnityException("Failed to create texture because of invalid parameters.");
    }

    [FreeFunction(Name = "CubemapScripting::Apply", HasExplicitThis = true)]
    [MethodImpl(MethodImplOptions.InternalCall)]
    private extern void ApplyImpl(bool updateMipmaps, bool makeNoLongerReadable);

    /// <summary>
    ///   <para>Updates Unity cubemap to use different native cubemap texture object.</para>
    /// </summary>
    /// <param name="nativeTexture">Native cubemap texture object.</param>
    [FreeFunction("CubemapScripting::UpdateExternalTexture", HasExplicitThis = true)]
    [MethodImpl(MethodImplOptions.InternalCall)]
    public extern void UpdateExternalTexture(IntPtr nativeTexture);

    public override extern bool isReadable { [MethodImpl(MethodImplOptions.InternalCall)] get; }

    [NativeName("SetPixel")]
    private void SetPixelImpl(int image, int mip, int x, int y, Color color)
    {
      this.SetPixelImpl_Injected(image, mip, x, y, ref color);
    }

    [NativeName("GetPixel")]
    private Color GetPixelImpl(int image, int mip, int x, int y)
    {
      Color ret;
      this.GetPixelImpl_Injected(image, mip, x, y, out ret);
      return ret;
    }

    /// <summary>
    ///   <para>Performs smoothing of near edge regions.</para>
    /// </summary>
    /// <param name="smoothRegionWidthInPixels">Pixel distance at edges over which to apply smoothing.</param>
    [NativeName("FixupEdges")]
    [MethodImpl(MethodImplOptions.InternalCall)]
    public extern void SmoothEdges([DefaultValue("1")] int smoothRegionWidthInPixels);

    public void SmoothEdges() => this.SmoothEdges(1);

    /// <summary>
    ///   <para>Gets the pixel color data for a mipmap level of a face as Color structs.</para>
    /// </summary>
    /// <param name="face">The CubemapFace to read from.</param>
    /// <param name="miplevel">The mipmap level to get. The range is 0 through the texture's Texture.mipmapCount. The default value is 0.</param>
    /// <returns>
    ///   <para>An array that contains the pixel colors.</para>
    /// </returns>
    [FreeFunction(Name = "CubemapScripting::GetPixels", HasExplicitThis = true, ThrowsException = true)]
    [MethodImpl(MethodImplOptions.InternalCall)]
    public extern Color[] GetPixels(CubemapFace face, int miplevel);

    /// <summary>
    ///   <para>Gets the pixel color data for a mipmap level of a face as Color structs.</para>
    /// </summary>
    /// <param name="face">The CubemapFace to read from.</param>
    /// <param name="miplevel">The mipmap level to get. The range is 0 through the texture's Texture.mipmapCount. The default value is 0.</param>
    /// <returns>
    ///   <para>An array that contains the pixel colors.</para>
    /// </returns>
    public Color[] GetPixels(CubemapFace face) => this.GetPixels(face, 0);

    /// <summary>
    ///   <para>Sets the pixel colors of an entire mipmap level of a face.</para>
    /// </summary>
    /// <param name="colors">The array of pixel colours to use. This is a 2D image flattened to a 1D array.</param>
    /// <param name="miplevel">The mipmap level to write colors to. The range is 0 through the texture's Texture.mipmapCount. The default value is 0.</param>
    /// <param name="face">The CubemapFace to write colors to.</param>
    [FreeFunction(Name = "CubemapScripting::SetPixels", HasExplicitThis = true, ThrowsException = true)]
    [MethodImpl(MethodImplOptions.InternalCall)]
    public extern void SetPixels([Unmarshalled] Color[] colors, CubemapFace face, int miplevel);

    [FreeFunction(Name = "CubemapScripting::SetPixelDataArray", HasExplicitThis = true, ThrowsException = true)]
    [MethodImpl(MethodImplOptions.InternalCall)]
    private extern bool SetPixelDataImplArray(
      Array data,
      int mipLevel,
      int face,
      int elementSize,
      int dataArraySize,
      int sourceDataStartIndex = 0);

    [FreeFunction(Name = "CubemapScripting::SetPixelData", HasExplicitThis = true, ThrowsException = true)]
    [MethodImpl(MethodImplOptions.InternalCall)]
    private extern bool SetPixelDataImpl(
      IntPtr data,
      int mipLevel,
      int face,
      int elementSize,
      int dataArraySize,
      int sourceDataStartIndex = 0);

    /// <summary>
    ///   <para>Sets the pixel colors of an entire mipmap level of a face.</para>
    /// </summary>
    /// <param name="colors">The array of pixel colours to use. This is a 2D image flattened to a 1D array.</param>
    /// <param name="miplevel">The mipmap level to write colors to. The range is 0 through the texture's Texture.mipmapCount. The default value is 0.</param>
    /// <param name="face">The CubemapFace to write colors to.</param>
    public void SetPixels(Color[] colors, CubemapFace face) => this.SetPixels(colors, face, 0);

    private AtomicSafetyHandle GetSafetyHandleForSlice(int mipLevel, int face)
    {
      AtomicSafetyHandle ret;
      this.GetSafetyHandleForSlice_Injected(mipLevel, face, out ret);
      return ret;
    }

    [MethodImpl(MethodImplOptions.InternalCall)]
    private extern IntPtr GetWritableImageData(int frame);

    internal extern bool isPreProcessed { [MethodImpl(MethodImplOptions.InternalCall)] get; }

    /// <summary>
    ///   <para>Determines whether mipmap streaming is enabled for this Texture.</para>
    /// </summary>
    public extern bool streamingMipmaps { [MethodImpl(MethodImplOptions.InternalCall)] get; }

    /// <summary>
    ///   <para>Sets the relative priority for this Texture when reducing memory size to fit within the memory budget.</para>
    /// </summary>
    public extern int streamingMipmapsPriority { [MethodImpl(MethodImplOptions.InternalCall)] get; }

    /// <summary>
    ///   <para>The mipmap level to load.</para>
    /// </summary>
    public extern int requestedMipmapLevel { [FreeFunction(Name = "GetTextureStreamingManager().GetRequestedMipmapLevel", HasExplicitThis = true), MethodImpl(MethodImplOptions.InternalCall)] get; [FreeFunction(Name = "GetTextureStreamingManager().SetRequestedMipmapLevel", HasExplicitThis = true), MethodImpl(MethodImplOptions.InternalCall)] set; }

    internal extern bool loadAllMips { [FreeFunction(Name = "GetTextureStreamingManager().GetLoadAllMips", HasExplicitThis = true), MethodImpl(MethodImplOptions.InternalCall)] get; [FreeFunction(Name = "GetTextureStreamingManager().SetLoadAllMips", HasExplicitThis = true), MethodImpl(MethodImplOptions.InternalCall)] set; }

    /// <summary>
    ///   <para>The mipmap level that the streaming system would load before memory budgets are applied.</para>
    /// </summary>
    public extern int desiredMipmapLevel { [FreeFunction(Name = "GetTextureStreamingManager().GetDesiredMipmapLevel", HasExplicitThis = true), MethodImpl(MethodImplOptions.InternalCall)] get; }

    /// <summary>
    ///   <para>The mipmap level that the mipmap streaming system is in the process of loading.</para>
    /// </summary>
    public extern int loadingMipmapLevel { [FreeFunction(Name = "GetTextureStreamingManager().GetLoadingMipmapLevel", HasExplicitThis = true), MethodImpl(MethodImplOptions.InternalCall)] get; }

    /// <summary>
    ///   <para>The mipmap level that is currently loaded by the streaming system.</para>
    /// </summary>
    public extern int loadedMipmapLevel { [FreeFunction(Name = "GetTextureStreamingManager().GetLoadedMipmapLevel", HasExplicitThis = true), MethodImpl(MethodImplOptions.InternalCall)] get; }

    /// <summary>
    ///   <para>Resets the requestedMipmapLevel field.</para>
    /// </summary>
    [FreeFunction(Name = "GetTextureStreamingManager().ClearRequestedMipmapLevel", HasExplicitThis = true)]
    [MethodImpl(MethodImplOptions.InternalCall)]
    public extern void ClearRequestedMipmapLevel();

    /// <summary>
    ///   <para>Checks to see whether the mipmap level set by requestedMipmapLevel has finished loading.</para>
    /// </summary>
    /// <returns>
    ///   <para>True if the mipmap level requested by requestedMipmapLevel has finished loading.</para>
    /// </returns>
    [FreeFunction(Name = "GetTextureStreamingManager().IsRequestedMipmapLevelLoaded", HasExplicitThis = true)]
    [MethodImpl(MethodImplOptions.InternalCall)]
    public extern bool IsRequestedMipmapLevelLoaded();

    internal bool ValidateFormat(TextureFormat format, int width)
    {
      bool flag = this.ValidateFormat(format);
      if (flag && TextureFormat.PVRTC_RGB2 <= format && format <= TextureFormat.PVRTC_RGBA4 && !Mathf.IsPowerOfTwo(width))
        throw new UnityException(string.Format("'{0}' demands texture to have power-of-two dimensions", (object) format.ToString()));
      return flag;
    }

    internal bool ValidateFormat(GraphicsFormat format, int width)
    {
      bool flag = this.ValidateFormat(format, FormatUsage.Sample);
      if (flag && GraphicsFormatUtility.IsPVRTCFormat(format) && !Mathf.IsPowerOfTwo(width))
        throw new UnityException(string.Format("'{0}' demands texture to have power-of-two dimensions", (object) format.ToString()));
      return flag;
    }

    [ExcludeFromDocs]
    public Cubemap(int width, DefaultFormat format, TextureCreationFlags flags)
      : this(width, SystemInfo.GetGraphicsFormat(format), flags)
    {
    }

    [RequiredByNativeCode]
    [ExcludeFromDocs]
    public Cubemap(int width, GraphicsFormat format, TextureCreationFlags flags)
    {
      if (!this.ValidateFormat(format, width))
        return;
      Cubemap.Internal_Create(this, width, Texture.GenerateAllMips, format, this.GetTextureColorSpace(format), flags, IntPtr.Zero);
    }

    public Cubemap(int width, TextureFormat format, int mipCount)
      : this(width, format, mipCount, IntPtr.Zero)
    {
    }

    [ExcludeFromDocs]
    public Cubemap(int width, GraphicsFormat format, TextureCreationFlags flags, int mipCount)
    {
      if (!this.ValidateFormat(format, width))
        return;
      Cubemap.ValidateIsNotCrunched(flags);
      Cubemap.Internal_Create(this, width, mipCount, format, this.GetTextureColorSpace(format), flags, IntPtr.Zero);
    }

    internal Cubemap(int width, TextureFormat textureFormat, int mipCount, IntPtr nativeTex)
    {
      if (!this.ValidateFormat(textureFormat, width))
        return;
      GraphicsFormat graphicsFormat = GraphicsFormatUtility.GetGraphicsFormat(textureFormat, false);
      TextureCreationFlags flags = mipCount != 1 ? TextureCreationFlags.MipChain : TextureCreationFlags.None;
      if (GraphicsFormatUtility.IsCrunchFormat(textureFormat))
        flags |= TextureCreationFlags.Crunch;
      Cubemap.ValidateIsNotCrunched(flags);
      Cubemap.Internal_Create(this, width, mipCount, graphicsFormat, this.GetTextureColorSpace(true), flags, nativeTex);
    }

    internal Cubemap(int width, TextureFormat textureFormat, bool mipChain, IntPtr nativeTex)
      : this(width, textureFormat, mipChain ? -1 : 1, nativeTex)
    {
    }

    /// <summary>
    ///   <para>Create a new empty cubemap texture.</para>
    /// </summary>
    /// <param name="size">Width/height of a cube face in pixels.</param>
    /// <param name="format">Pixel data format to be used for the Cubemap.</param>
    /// <param name="mipmap">Should mipmaps be created?</param>
    /// <param name="width"></param>
    /// <param name="textureFormat"></param>
    /// <param name="mipChain"></param>
    public Cubemap(int width, TextureFormat textureFormat, bool mipChain)
      : this(width, textureFormat, mipChain ? -1 : 1, IntPtr.Zero)
    {
    }

    /// <summary>
    ///   <para>Creates a Unity cubemap out of externally created native cubemap object.</para>
    /// </summary>
    /// <param name="size">The width and height of each face of the cubemap should be the same.</param>
    /// <param name="format">Format of underlying cubemap object.</param>
    /// <param name="mipmap">Does the cubemap have mipmaps?</param>
    /// <param name="nativeTex">Native cubemap texture object.</param>
    /// <param name="width"></param>
    public static Cubemap CreateExternalTexture(
      int width,
      TextureFormat format,
      bool mipmap,
      IntPtr nativeTex)
    {
      if (nativeTex == IntPtr.Zero)
        throw new ArgumentException("nativeTex can not be null");
      return new Cubemap(width, format, mipmap, nativeTex);
    }

    public void SetPixelData<T>(
      T[] data,
      int mipLevel,
      CubemapFace face,
      [DefaultValue("0")] int sourceDataStartIndex = 0)
    {
      if (sourceDataStartIndex < 0)
        throw new UnityException("SetPixelData: sourceDataStartIndex cannot be less than 0.");
      if (!this.isReadable)
        throw this.CreateNonReadableException((Texture) this);
      if (data == null || data.Length == 0)
        throw new UnityException("No texture data provided to SetPixelData.");
      this.SetPixelDataImplArray((Array) data, mipLevel, (int) face, Marshal.SizeOf((object) data[0]), data.Length, sourceDataStartIndex);
    }

    public unsafe void SetPixelData<T>(
      NativeArray<T> data,
      int mipLevel,
      CubemapFace face,
      [DefaultValue("0")] int sourceDataStartIndex = 0)
      where T : struct
    {
      if (sourceDataStartIndex < 0)
        throw new UnityException("SetPixelData: sourceDataStartIndex cannot be less than 0.");
      if (!this.isReadable)
        throw this.CreateNonReadableException((Texture) this);
      if (!data.IsCreated || data.Length == 0)
        throw new UnityException("No texture data provided to SetPixelData.");
      this.SetPixelDataImpl((IntPtr) data.GetUnsafeReadOnlyPtr<T>(), mipLevel, (int) face, UnsafeUtility.SizeOf<T>(), data.Length, sourceDataStartIndex);
    }

    public unsafe NativeArray<T> GetPixelData<T>(int mipLevel, CubemapFace face) where T : struct
    {
      if (!this.isReadable)
        throw this.CreateNonReadableException((Texture) this);
      if (mipLevel < 0 || mipLevel >= this.mipmapCount)
        throw new ArgumentException("The passed in miplevel " + mipLevel.ToString() + " is invalid. The valid range is 0 through " + (this.mipmapCount - 1).ToString());
      if (face < CubemapFace.PositiveX || face >= (CubemapFace.PositiveY | CubemapFace.PositiveZ))
        throw new ArgumentException("The passed in face " + face.ToString() + " is invalid. The valid range is 0 through 5.");
      if (this.GetWritableImageData(0).ToInt64() == 0L)
        throw new UnityException("Texture '" + this.name + "' has no data.");
      ulong pixelDataOffset1 = this.GetPixelDataOffset(this.mipmapCount, (int) face);
      ulong pixelDataOffset2 = this.GetPixelDataOffset(mipLevel, (int) face);
      ulong length = this.GetPixelDataSize(mipLevel, (int) face) / (ulong) UnsafeUtility.SizeOf<T>();
      if (length > (ulong) int.MaxValue)
        throw this.CreateNativeArrayLengthOverflowException();
      NativeArray<T> nativeArray = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray<T>((void*) new IntPtr((long) this.GetWritableImageData(0) + ((long) pixelDataOffset1 * (long) face + (long) pixelDataOffset2)), (int) length, Allocator.None);
      NativeArrayUnsafeUtility.SetAtomicSafetyHandle<T>(ref nativeArray, this.GetSafetyHandleForSlice(mipLevel, (int) face));
      return nativeArray;
    }

    /// <summary>
    ///   <para>Sets the pixel color at coordinates (x,y).</para>
    /// </summary>
    /// <param name="x">The x coordinate of the pixel to set. The range is 0 through (texture width - 1).</param>
    /// <param name="y">The y coordinate of the pixel to set. The range is 0 through (texture height - 1).</param>
    /// <param name="color">The color to set.</param>
    /// <param name="mip">The mipmap level to write to. The range is 0 through the texture's Texture.mipmapCount. The default value is 0.</param>
    /// <param name="face">The CubemapFace to write to.</param>
    [ExcludeFromDocs]
    public void SetPixel(CubemapFace face, int x, int y, Color color)
    {
      this.SetPixel(face, x, y, color, 0);
    }

    /// <summary>
    ///   <para>Sets the pixel color at coordinates (x,y).</para>
    /// </summary>
    /// <param name="x">The x coordinate of the pixel to set. The range is 0 through (texture width - 1).</param>
    /// <param name="y">The y coordinate of the pixel to set. The range is 0 through (texture height - 1).</param>
    /// <param name="color">The color to set.</param>
    /// <param name="mip">The mipmap level to write to. The range is 0 through the texture's Texture.mipmapCount. The default value is 0.</param>
    /// <param name="face">The CubemapFace to write to.</param>
    public void SetPixel(CubemapFace face, int x, int y, Color color, [DefaultValue("0")] int mip)
    {
      if (!this.isReadable)
        throw this.CreateNonReadableException((Texture) this);
      this.SetPixelImpl((int) face, mip, x, y, color);
    }

    /// <summary>
    ///   <para>Gets the pixel color at coordinates (x, y).</para>
    /// </summary>
    /// <param name="x">The x coordinate of the pixel to get. The range is 0 through (texture width - 1).</param>
    /// <param name="y">The y coordinate of the pixel to get. The range is 0 through (texture height - 1).</param>
    /// <param name="mip">The mipmap level to sample. The range is 0 through the texture's Texture.mipmapCount. The default value is 0.</param>
    /// <param name="face">The CubemapFace to sample.</param>
    /// <returns>
    ///   <para>The pixel color.</para>
    /// </returns>
    [ExcludeFromDocs]
    public Color GetPixel(CubemapFace face, int x, int y) => this.GetPixel(face, x, y, 0);

    /// <summary>
    ///   <para>Gets the pixel color at coordinates (x, y).</para>
    /// </summary>
    /// <param name="x">The x coordinate of the pixel to get. The range is 0 through (texture width - 1).</param>
    /// <param name="y">The y coordinate of the pixel to get. The range is 0 through (texture height - 1).</param>
    /// <param name="mip">The mipmap level to sample. The range is 0 through the texture's Texture.mipmapCount. The default value is 0.</param>
    /// <param name="face">The CubemapFace to sample.</param>
    /// <returns>
    ///   <para>The pixel color.</para>
    /// </returns>
    public Color GetPixel(CubemapFace face, int x, int y, [DefaultValue("0")] int mip)
    {
      if (!this.isReadable)
        throw this.CreateNonReadableException((Texture) this);
      return this.GetPixelImpl((int) face, mip, x, y);
    }

    /// <summary>
    ///   <para>Copies changes you've made in a CPU texture to the GPU.</para>
    /// </summary>
    /// <param name="updateMipmaps">When the value is true, Unity recalculates mipmap levels, using mipmap level 0 as the source. The default value is true.</param>
    /// <param name="makeNoLongerReadable">When the value is true, Unity deletes the texture in CPU memory after it uploads it to the GPU, and sets Texture.isReadable|isReadable to false. The default value is false.</param>
    public void Apply([DefaultValue("true")] bool updateMipmaps, [DefaultValue("false")] bool makeNoLongerReadable)
    {
      this.ApplyImpl(updateMipmaps, makeNoLongerReadable);
    }

    [ExcludeFromDocs]
    public void Apply(bool updateMipmaps) => this.Apply(updateMipmaps, false);

    [ExcludeFromDocs]
    public void Apply() => this.Apply(true, false);

    private static void ValidateIsNotCrunched(TextureCreationFlags flags)
    {
      if ((flags &= TextureCreationFlags.Crunch) != 0)
        throw new ArgumentException("Crunched Cubemap is not supported for textures created from script.");
    }

    [MethodImpl(MethodImplOptions.InternalCall)]
    private extern void SetPixelImpl_Injected(int image, int mip, int x, int y, ref Color color);

    [MethodImpl(MethodImplOptions.InternalCall)]
    private extern void GetPixelImpl_Injected(int image, int mip, int x, int y, out Color ret);

    [MethodImpl(MethodImplOptions.InternalCall)]
    private extern void GetSafetyHandleForSlice_Injected(
      int mipLevel,
      int face,
      out AtomicSafetyHandle ret);
  }
}
